package lib.map;

/**
 * This class represents a Cellular Automaton as we know it from cs101 in
 * exercise 9. It allows to apply Cellular-Automaton-style rules to our map.
 * */
public class CellularAutomaton {
	public boolean[][] cell;

	public CellularAutomaton(boolean[][] cell) {
		this.cell = cell;
	}

	public boolean[][] calcNextGeneration(boolean[][] cell) {
		int n = 0;
		boolean[][] ncell = new boolean[cell.length][cell[0].length];
		for (int i = 0; i < cell.length; i++) {
			for (int j = 0; j < cell[0].length; j++) {
				n = countAliveNeighbours(cell, i, j);
				ncell[i][j] = cell[i][j];
				if (!cell[i][j]) {// birth
					if (n == 3) {
						ncell[i][j] = true;
					}
				} else {// survival or overcrowding:
					if (n == 2 || n == 3) {// survival
					} else {// overcrowding
						ncell[i][j] = false;
					}
				}
			}
		}
		return ncell;
	}

	public int countAliveNeighbours(boolean[][] cell, int z, int s) {
		int livingN = 0;
		int a = 0, b = 0;
		for (int i = -1; i <= 1; i++) {
			for (int j = -1; j <= 1; j++) {
				a = (z + i) % (cell.length);
				b = (s + j) % (cell[0].length);
				if (a < 0)
					a = cell.length - 1;
				if (b < 0)
					b = cell[0].length - 1;
				if (cell[a][b])
					livingN++;
			}
		}
		if (cell[z][s])
			livingN--;
		return livingN;
	}

	public String toString(boolean[][] cell) {
		String s="";
		for (int i = 0; i < cell.length; i++) {
			for (int j = 0; j < cell[0].length; j++) {
				if (cell[i][j])
					s+="X";
				else
					s+="0";
			}
			s+="\n";
		}
		return s;
	}
}
